package idv.arthur.prac;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;

import org.apache.commons.io.FileUtils;
import org.tmatesoft.svn.core.ISVNDirEntryHandler;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNEvent;
import org.tmatesoft.svn.core.wc.SVNEventAction;
import org.tmatesoft.svn.core.wc.SVNLogClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;

public class SvnTest {
	static {
		DAVRepositoryFactory.setup();
	}

	private SVNClientManager manager;
	private SVNURL repositoryBaseUrl;
	static ArrayList<DirStruc> dirStrucs = new ArrayList<DirStruc>();
	//private String url = "http://10.144.136.56/svntest/arthur/DPS";
	private String url = "http://arthur-pc.cht.com.tw/svn/AirForce/";
	
	public SvnTest() {
		DefaultSVNOptions options = new DefaultSVNOptions();
		// manager = SVNClientManager.newInstance(options);
		manager = SVNClientManager.newInstance(options, "Arthur", "abcd1234"); // 如果需要用戶名密碼
		try {
			repositoryBaseUrl = SVNURL
					.parseURIEncoded(url); // 傳入svn地址
		} catch (SVNException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public class DirEntryHandler implements ISVNDirEntryHandler {
		@Override
		public void handleDirEntry(SVNDirEntry dirEntry) throws SVNException {
			System.out.print("****DirEntryHandler.handleDirEntry.()****");
			String parentDir = "沒算出來...";
			String path = dirEntry.getRelativePath();
			if (dirEntry.getKind() == SVNNodeKind.DIR) { // 是目錄
				if (!path.equalsIgnoreCase("")) {
					if (!path.contains("/")) {
						parentDir = "根目錄";
					} else {
						parentDir = path.substring(0,
								path.lastIndexOf(dirEntry.getName()) - 1);
						/*
						 * for(String dirPath:dirStrucs) { if
						 * (path.indexOf((dirPath+"/"))==0) { parentDir =
						 * dirPath; } }
						 */
					}
					System.out.println("目錄：" + path + "上層目錄是：" + parentDir);
					DirStruc ds = new DirStruc();
					ds.setDir(true);
					ds.setHome(parentDir);
					ds.setId(path);
					dirStrucs.add(ds);
				}
			} else if (dirEntry.getKind() == SVNNodeKind.FILE) {
				if (!path.contains("/")) {
					parentDir = "根目錄";
				} else {
					parentDir = path.substring(0,
							path.lastIndexOf(dirEntry.getName()) - 1);
				}
				System.out.println("檔案：" + path + "在那個目錄裡：" + parentDir + "  版本：" + dirEntry.getRevision());
				DirStruc ds = new DirStruc();
				ds.setDir(false);
				ds.setHome(parentDir.replaceAll("/", "|||"));
				ds.setId(dirEntry.getName().replaceAll("/", "|||"));
				ds.setVer(dirEntry.getRevision());
				dirStrucs.add(ds);
			} else {
				System.out.println("有問題" + dirEntry.getKind());
			}
		}
	}

	public void test() throws SVNException {
		SVNLogClient logClient = manager.getLogClient();

		// svn list
		DirEntryHandler handler = new DirEntryHandler(); // 在svn

		// co時對每個文件目錄的處理，實現ISVNDirEntryHandler接口
		long star = System.currentTimeMillis();
		logClient.doList(repositoryBaseUrl, SVNRevision.HEAD, SVNRevision.HEAD,
				false, true, handler); // 列出當前svn地址的目錄，對每個文件進行處理
		long end = System.currentTimeMillis();
		
		Date dt = new Date((end-star));
		
		System.out.println("結束，共花了："+dt.getSeconds()+"秒");
		// svn co
		UpdateEventHandler svnEventHandler = new UpdateEventHandler(); // svnco時對每個文件的處理
		SVNUpdateClient client = manager.getUpdateClient();
		client.setIgnoreExternals(true);
		client.setEventHandler(svnEventHandler);
		
		//File to = new File("D:\\temp"); // co出來的文件存放目錄
		/*client.doCheckout(repositoryBaseUrl, to, SVNRevision.HEAD,
				SVNRevision.HEAD, SVNDepth.INFINITY, false);*/
		// svn update
		/*client.setIgnoreExternals(true);
		client.setEventHandler(svnEventHandler);
		client.doUpdate(to, SVNRevision.HEAD, SVNDepth.INFINITY, true, false);*/

	}

	public static void main(String[] args) throws SVNException {
		SvnTest svntest = new SvnTest();
		svntest.test();
		//String ttt = new Gson().toJson(dirStrucs).toString();
		//System.out.println("\n\n" + ttt);
	}

	public class UpdateEventHandler implements ISVNEventHandler {
		public void handleEvent(SVNEvent event, double progress) {
			System.out.println("****UpdateEventHandler.handleEvent()****");
			SVNEventAction action = event.getAction();
			SVNNodeKind nodeKind = event.getNodeKind();

			if (SVNNodeKind.DIR.equals(nodeKind)) {
				// folder
				System.out.println(event.getFile().getName());
			} else {
				// treat as file for all other type

				if (action == SVNEventAction.UPDATE_DELETE) {
					try {
						System.out.println(event.getFile().getName() + "\t"
								+ FileUtils.readFileToString(event.getFile())
								+ "====>現的Revision是：" + event.getRevision());

					} catch (IOException e) {

					}
				} else if (action == SVNEventAction.UPDATE_ADD
						|| action == SVNEventAction.UPDATE_UPDATE) {
					try {
						System.out.println(event.getFile().getName() + "\t"
								+ FileUtils.readFileToString(event.getFile())
								+ "====>現的Revision是：" + event.getRevision());

					} catch (IOException e) {

					}
				}
			}
		}

		public void checkCancelled() throws SVNCancelException {
		}

	}

	class DirStruc {
		boolean isDir;
		long ver;
		String id;
		String home;

		public boolean isDir() {
			return isDir;
		}

		public void setDir(boolean isDir) {
			this.isDir = isDir;
		}

		public long getVer() {
			return ver;
		}

		public void setVer(long ver) {
			this.ver = ver;
		}

		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getHome() {
			return home;
		}

		public void setHome(String home) {
			this.home = home;
		}

	}
}
